/**
 * 最大值与方案总数同时求
 * 规划方程也比较显而易见
 */
using llt = long long;
llt const MOD = 1E9 + 7;
int const None = -1;

struct _t{
    int maxv;
    llt cnt;
    static const _t & none(){
        static const _t _{None, (llt)None};
        return _;
    }
    vector<int> tovec()const{
        if(maxv != None) return {maxv, (int)cnt};
        return {0, 0};
    }
};

class Solution {

int N, M;
vector<vector<_t>> D;

public:
    vector<int> pathsWithMaxScore(vector<string>& board) {
        N = board.size();
        M = board[0].size();
        D.assign(N, vector<_t>(M, _t::none()));

        D[0][0] = {0, 1LL};
        for(int i=0;i<N;++i)for(int j=0;j<M;++j){
            if(0 == i  and 0 == j) continue;
            if('X' == board[i][j]) continue;

            int v = 0;
            if(i + 1 != N or j + 1 != M) v = board[i][j] - '0';
            auto & d = D[i][j];
            if(i > 0){
                chkUpdate(d, D[i - 1][j]);
            } 
            if(j > 0){
                chkUpdate(d, D[i][j - 1]);
            }
            if(i > 0 and j > 0){
                chkUpdate(d, D[i - 1][j - 1]);
            }
            if(d.maxv != None) d.maxv += v;
        }

        return D[N - 1][M - 1].tovec();
    }

    void chkUpdate(_t&d, const _t & a){
        if(a.maxv == None) return;
        if(d.maxv == None or d.maxv < a.maxv) return (void)(d = a);
        if(d.maxv == a.maxv) return (void)(d.cnt = (d.cnt + a.cnt) % MOD);
        return;
    }
};